package com.bvgol.example.rabbitmq;/**
 * @Classname T
 * @Description TODO
 * @Date 2021/3/17 14:02
 * @Created by GUOCHEN
 */

import com.bvgol.example.rabbitmq.constant.Name;
import lombok.extern.slf4j.Slf4j;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.amqp.core.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

import java.time.Instant;

/**
 * @program: my-spring-completely
 * @description:
 * @author: GUOCHEN
 * @create: 2021/03/17 14:02
 */
@Slf4j
@RunWith(SpringRunner.class)
@SpringBootTest
public class Create {

    @Autowired
    AmqpAdmin amqpAdmin;

    //how to create exchange/queue/binding
    //how to publish message and get message

    @Test
    public void name() {
        //页面操作 都有对应的操作api
        //创建 队列
//        amqpAdmin.declareQueue();
//        创建交换机
//        amqpAdmin.declareExchange();
        //创建队列和交换机的绑定关系
//        amqpAdmin.declareBinding();
        log.info("---->[{}]<----", Instant.now());
        //2021-03-17 14:15:17.987  INFO 3876 --- [           main] com.bvgol.example.rabbitmq.T             : ---->[2021-03-17T06:15:17.987Z]<----
    }

    /**
     * 1、如何创建Exchange、Queue、Binding
     * 1）、使用AmqpAdmin进行创建
     * 2、如何收发消息
     */
    @Test
    public void createExchange() {

        Exchange directExchange = new DirectExchange(Name.exchangeName, true, false);
        amqpAdmin.declareExchange(directExchange);
        log.info("Exchange[{}]创建成功：", Name.exchangeName);
    }

    @Test
    public void testCreateQueue() {
        Queue queue = new Queue(Name.queueName, true, false, false);
        amqpAdmin.declareQueue(queue);
        log.info("Queue[{}]创建成功：", Name.queueName);
        Queue queue2 = new Queue(Name.queueName2, true, false, false);
        amqpAdmin.declareQueue(queue2);
        log.info("Queue[{}]创建成功：", Name.queueName2);
    }

    @Test
    public void createBinding() {

        Binding binding = new Binding(Name.queueName,
                Binding.DestinationType.QUEUE,
                Name.exchangeName,
                "hello.java",
                null);
        amqpAdmin.declareBinding(binding);
        Binding binding2 = new Binding(Name.queueName2,
                Binding.DestinationType.QUEUE,
                Name.exchangeName,
                "hello.java",
                null);
        amqpAdmin.declareBinding(binding2);
        log.info("Binding[{}]创建成功：", "hello-java-binding");

    }

//Direct Exchange   直连型交换机，根据消息携带的路由键将消息投递给对应队列。
//
//大致流程，有一个队列绑定到一个直连交换机上，同时赋予一个路由键 routing key 。
//然后当一个消息携带着路由值为X，这个消息通过生产者发送给交换机时，交换机就会根据这个路由值X去寻找绑定值也是X的队列。
//
//Fanout Exchange 扇型交换机，这个交换机没有路由键概念，就算你绑了路由键也是无视的。 这个交换机在接收到消息后，会直接转发到绑定到它上面的所有队列。
//
//Topic Exchange 主题交换机，这个交换机其实跟直连交换机流程差不多，但是它的特点就是在它的路由键和绑定键之间是有规则的。
//简单地介绍下规则：
//
//*  (星号) 用来表示一个单词 (必须出现的)
//#  (井号) 用来表示任意数量（零个或多个）单词
//通配的绑定键是跟队列进行绑定的，举个小例子
//队列Q1 绑定键为 *.TT.*          队列Q2绑定键为  TT.#
//如果一条消息携带的路由键为 A.TT.B，那么队列Q1将会收到；
//如果一条消息携带的路由键为TT.AA.BB，那么队列Q2将会收到；
//
//主题交换机是非常强大的，为啥这么膨胀？
//当一个队列的绑定键为 "#"（井号） 的时候，这个队列将会无视消息的路由键，接收所有的消息。
//当 * (星号) 和 # (井号) 这两个特殊字符都未在绑定键中出现的时候，此时主题交换机就拥有的直连交换机的行为。
//所以主题交换机也就实现了扇形交换机的功能，和直连交换机的功能。
//
//另外还有 Header Exchange 头交换机 ，Default Exchange 默认交换机，Dead Letter Exchange 死信交换机

}
